package mathy.wili.c;
import java.lang.reflect.Array;
import java.lang.reflect.Executable;
import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtConstructor;
/**
 * 
 * @author weila 2021年2月15日
 */
public class Javaassist9 {
	@SuppressWarnings("unchecked")
	public static <T extends Executable> T ctMethod_toMethod(CtBehavior md, ClassPool cp) {
		Class<?> cls = Javaassist9.ctClass_toClass(md.getDeclaringClass(), cp);
		CtClass[] cc2;
		try {
			cc2 = md.getParameterTypes();
			Class<?>[] cc = new Class[cc2.length];
			for (int i = 0; i < cc.length; i++) {
				cc[i] = Javaassist9.ctClass_toClass(cc2[i], cp);
			}
			if (md instanceof CtConstructor)
				return (T) cls.getDeclaredConstructor(cc);
			return (T) cls.getDeclaredMethod(md.getName(), cc);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	static Class<?> ctClass_toClass(CtClass cls, ClassPool cp) {
		if (cls.isArray()) {
			try {
				CtClass ct = cls.getComponentType();
				Class<?> ret = ctClass_toClass(ct, cp);
				Object obj = Array.newInstance(ret, 1);
				return obj.getClass();
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}
		String cname = cls.getName();
		switch (cname) {
		case "boolean":
			return boolean.class;
		case "byte":
			return byte.class;
		case "char":
			return char.class;
		case "short":
			return short.class;
		case "int":
			return int.class;
		case "long":
			return long.class;
		case "float":
			return float.class;
		case "double":
			return double.class;
		case "java.lang.Object":
		default: {
			try {
				return Class.forName(cname);
			} catch (Throwable ee) {
				try {
					if (ee instanceof Error)
						return null;
					return cp.toClass(cls);
				} catch (Exception e2) {
					e2.printStackTrace();
					return null;
				}
			}
		}
		}
	}
}